package com.joyintech.config;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.joyintech.annotation.Dict;
import com.joyintech.modules.system.service.dto.DictDetailDto;
import com.joyintech.modules.system.service.mapper.DictDetailMapper;
import com.joyintech.utils.SpringContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.*;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.sql.Statement;
import java.util.*;

/**
 * 结果拦截器
 * @program: eladmin
 * @description:
 * @author: daiweiwei@joyintech.com
 * @create: 2022-03-13 14:52
 */
@Intercepts({
        @Signature(type = ResultSetHandler.class, method = "handleResultSets", args={Statement.class})
})
@Component
@Slf4j
public class ResultInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        log.info("ResultSetHandler:handleResultSets 拦截器处理数据库表落标字段映射字典值...");
        Object result = invocation.proceed();
        if (Objects.isNull(result)) return null;

        if (result instanceof ArrayList) {
            ArrayList resultList = (ArrayList) result;
            if (CollectionUtils.isNotEmpty(resultList)){
                resultList.stream().forEach(o -> changeDict(o,invocation));
            }
        }else {
            changeDict(result,invocation);
        }
        return result;
    }


    public void changeDict(Object result,Invocation invocation){
        Class<?> objectClass = result.getClass();
        Field[] declaredFields = objectClass.getDeclaredFields();
        Arrays.asList(declaredFields).stream().filter(field ->Objects.nonNull(AnnotationUtils.findAnnotation(field, Dict.class) )).forEach(field -> {
            Dict dictClass = AnnotationUtils.findAnnotation(field, Dict.class);
            try {
                field.setAccessible(true);
                if(dictClass.mark()){
                    DictDetailDto dictDetail = getDictDetail(dictClass.dict(), String.valueOf(field.get(result)));
                    field.set(result,dictDetail.getValue());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        });

    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }
    private DictDetailDto getDictDetail(String dictName,String mark){
        DictDetailMapper dictDetailMapper = SpringContextHolder.getBean(DictDetailMapper.class);
        List<DictDetailDto> ret = dictDetailMapper.getDictDetailsByDictName(dictName);
        if(Objects.isNull(ret)) return null;
        return  ret.stream().filter(dto -> dto.getMark().equals(mark)).findAny().orElse(new DictDetailDto());
    }
}
